home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / answrbok / 6_11.lha / 6_11 / 6_11_cd.c < prev    next >
Text File  |  1993-08-08  |  2KB  |  98 lines

  1. * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
  2. * The C++ Answer Book */
  3. * Tony Hansen */
  4. * All rights reserved. */
  5. *
  6.    Constructor and assignment of doubles
  7. /
  8. include <math.h>
  9. include <limits.h>
  10. include <float.h>
  11. include <arbint.h>
  12. include <swap.h>
  13.  
  14. *
  15.    Fill in an arep with a double.
  16.    Convert the double into a string
  17.    of ARB_type digits.
  18. /
  19. tatic void dassign(arep *p, double n)
  20.  
  21.    p->refcnt = 1;
  22.  
  23.    /* declare working storage for dtoarb */
  24.    define BITS(type)    (CHAR_BIT * (int)sizeof(type))
  25.    const int dlen = DBL_MAX_EXP / BITS(ARB_type);
  26.    ARB_type s[dlen+1];
  27.  
  28.    /* convert the double to positivt */
  29.    int neg = 0;
  30.    if (n < 0)
  31. {
  32. n = -n;
  33. neg = 1;
  34. }
  35.  
  36.    // convert the double
  37.    double i = n;
  38.    ARB_type *s1 = (s + neg);    // run forward on digits
  39.  
  40.    // this leaves the digits in reverse order
  41.    do  {
  42. *s1++ = (ARB_type) fmod(i, ARB_base);
  43. i /= ARB_base;
  44.    } while (i >= 1.0);
  45.  
  46.    // run forward and backward on
  47.    // the digits reversing them
  48.    p->length = s1-- - (s + neg);
  49.    ARB_type *s2 = s;
  50.    while (s2 < s1)
  51. swap(*s2++, *s1--);
  52.  
  53.    // if necessary, convert to negative
  54.    if (neg)
  55. {
  56. ARB_Ltype k = 1;
  57. s[0] = 0;
  58. p->length++;
  59. for (int j = p->length - 1; ; )
  60.     {
  61.     ARB_type l1 = ~s[j];
  62.     ARB_Ltype l = l1 + k;
  63.     s[j] = l;
  64.     if (--j <= 0)
  65.     break;
  66.     k = (l / ARB_base) ? 1 : 0;
  67.     }
  68. }
  69.  
  70.    // copy to allocated space
  71.    p->value = new ARB_type[p->length];
  72.    memcpy((char *)p->value, (char *)s,
  73. p->length * sizeof(ARB_type));
  74.  
  75.  
  76. * create an arbint from a double */
  77. rbint::arbint(double n)        // arbint x = 36.0;
  78.  
  79.    p = new arep;
  80.    dassign(p, n);
  81.  
  82.  
  83. * assign a double to an arbint */
  84. rbint& arbint::operator=(double n) // x = 36.0;
  85.  
  86.    if (p->refcnt > 1)
  87. {
  88. p->refcnt--;
  89. p = new arep;
  90. }
  91.  
  92.    else
  93. delete p->value;
  94.  
  95.    dassign(p, n);
  96.    return *this;
  97.  
  98.